#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#define AM2120_SDA 26
#define EEPROM_ADDR 0x50 // AT24C02默认地址
WiFiClient espClient;
PubSubClient client(espClient);
const char *ssid = "MiHome";
const char *password = "ftwc1982";
const char *mqtt_server = "192.168.3.254";
const char *userName = "lu";
const char *passWd = "5891381";
const char *clientID = "dsiclu_1_id";
int i;
int current_angle = 0, last_angle = 0;
double turn_count = 0;
// float test;
union double_byte
{
    byte b[8];
    double d;
};

void setupAM2120()
{

    pinMode(AM2120_SDA, OUTPUT);
    digitalWrite(AM2120_SDA, HIGH);
    //	pinMode(D8, OUTPUT);
    //	digitalWrite(D8, LOW);
}
void setup_wifi()
{

    delay(10);
    // We start by connecting to a WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
        digitalWrite(2, !digitalRead(2));
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}
void subscribe()
{
    client.subscribe("test");
}
void callback(char *topic, byte *payload, unsigned int length)
{
    unsigned int i;
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    char rMessage[length];
    for (i = 0; i < length; i++)
    {
        rMessage[i] = (char)payload[i];
    }
    rMessage[length] = '\0';
    Serial.println(rMessage);
    /*    if (strcmp(topic, powerButton) == 0)
        {
            if (strcmp(rMessage, "power") == 0)
            {
            }
            else if (strcmp(rMessage, "restart") == 0)
            {
            }
        }
        if (strcmp(topic, countDown) == 0)
        {
        }*/
}
void reconnect()
{
    // Loop until we're reconnected
    while (!client.connected())
    {
        Serial.print("Attempting MQTT connection...");

        if (client.connect(clientID, userName, passWd))
        {
            Serial.println("connected");
            // Once connected, publish an announcement...
            //    client.publish(computerState, "hello world");
            // ... and resubscribe
            subscribe();
        }
        else
        {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}
int Read_AS5600_Angle()
{
    //   double angle;
    int rawAngle;
    byte data[2];
    Wire.beginTransmission(0x36);
    Wire.write(0x0c);
    Wire.endTransmission();
    //    Wire.requestFrom(ADDRESS_AT24C32, sizeof(str));
    Wire.requestFrom(0x36, 2);

    for (int i = 0; i < 2; i++) // for (i = 0; i < sizeof(str)+10; i++)
    {
        data[i] = Wire.read();
    }
    Wire.endTransmission();
    rawAngle = (data[0] << 8) | data[1];
    //    angle = rawAngle / 4096.0 * 360.0;
    // return angle;
    return rawAngle;
}

void Update_Turn_Count()
{
    int diff;

    current_angle = Read_AS5600_Angle();

    // 计算角度差，考虑过零情况
    diff = (int)current_angle - (int)last_angle;

    // 如果角度差大于180度（4096/2=2048），则认为是逆时针过零，圈数减1
    if (diff > 2048)
    {
        turn_count -= 1;
    }
    // 如果角度差小于-180度，则认为是顺时针过零，圈数加1
    else if (diff < -2048)
    {
        turn_count += 1;
    }
    turn_count += diff / 4096.0;
    last_angle = current_angle;
}
void writeDoubleToEEPROM(unsigned int addr, double test)
{
    // 将double转换为字节数组

    byte *b = (byte *)&test;
    Wire.beginTransmission(EEPROM_ADDR);
    Wire.write(addr); // 目标地址
    // 分4次写入（AT24C02页大小为8字节）
    for (int i = 0; i < 8; i++)
    {
        Wire.write(b[i]); // 数据字节
        delay(5);
    }
    Wire.endTransmission();
    delay(5); // 等待写入完成（AT24C02需要5ms）
}

// 从EEPROM读取并组合为double
double readDoubleFromEEPROM(uint8_t addr)
{
    //  byte b[4];

    double value;
    byte *b = (byte *)&value;
    Wire.beginTransmission(0x50);
    Wire.write(addr);            // 目标地址
    Wire.endTransmission(false); // 保持连接
    Wire.requestFrom(0x50, 4);
    // 分4次读取
    for (int i = 0; i < 8 && Wire.available(); i++)
    {
        b[i] = Wire.read();
    }
    Wire.endTransmission();
    delay(5);
    return value;
}

void setup()
{
    // put your setup code here, to run once:
    Serial.begin(115200);
    pinMode(2, OUTPUT);
    //    setup_wifi();
    //    client.setServer(mqtt_server, 1883);
    //    client.setCallback(callback);
    //    client.connect(clientID, userName, passWd);
    //    subscribe();
    Wire.begin();
    delay(3000);
    //  Serial.printf("\n\n----%f\n", readDoubleFromEEPROM(0));
}

void loop()
{
    char m, n;
    m = 50;
    n = 2;
    /*   if (!client.connected())
        {
            reconnect();
        }
        client.loop();*/
    //   Update_Turn_Count();
    //   turn_count += calculateAngleDelta() / 4096.0;
    //   writeDoubleToEEPROM(0, turn_count);
    writeDoubleToEEPROM(m, 3.14159265358979323846 * n);

    //  n = readTest(&m, 10);
    //  readDoubleFromEEPROM(10);
    Serial.printf("R:%f\t%d\n", readDoubleFromEEPROM(m), m);
    Serial.println("-------");
    delay(1000);
}
